/*
 * Copyright (c) 2025 HiEasyX
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

/**
 * \file hex_dropdown.cpp
 * \brief The dropdown selector for HiEasyX
 */

#include <include/hex.h>
#include <include/hex_dropdown.h>

namespace HX {
HXGInt Dropdown(DropdownProfile &Profile) {
	auto &context = GetContext();
	auto &theme   = GetTheme();

	auto position = CurrentLayoutPosition();

	bool visible = true;

	if (RoughVisibility()) {
		return -1;
	}
	if (AccVisibility({Profile.Width, 22})) {
		visible = false;
	}

	bool returnSameLine = false;
	if (CurrentLayout()->InSameLine) {
		returnSameLine = true;
		EndSameLine();
	}

	if (visible) {
		auto painter = CurrentPainter();

		auto buttonRectangle = HXRect{position.X, position.Y, position.X + Profile.Width, position.Y + 22};
		auto triggerRectangle = HXRect{position.X, position.Y, position.X + Profile.Width, position.Y + 22 + 105};
		for (auto &Message : context.MessageQuery) {
			auto mouse = ClipCoord({Message.MouseX, Message.MouseY});
			if (Message.Processed) {
				continue;
			}
			if (Message.MouseAction) {
				if (buttonRectangle.PointInside(mouse) && Message.MouseLeftPressed) {
					Message.Processed = true;

					Profile.OnWorking = !Profile.OnWorking;
				} else if (!triggerRectangle.PointInside(mouse) && Message.MouseLeftPressed && Profile.OnWorking) {
					Profile.OnWorking = false;
				}
			}
		}

		painter->Begin();
		if (Profile.OnHover) {
			painter->DrawFilledRectangle(buttonRectangle,
										 theme.DropdownHoverBorder, theme.DropdownHoverBackground);
		} else {
			painter->DrawFilledRectangle(buttonRectangle,
										 theme.DropdownBorder, theme.DropdownBackground);
		}

		if (Profile.SelectingItem >= 0) {
			auto fontRect = painter->MeasureText(Profile.Items[Profile.SelectingItem].Title, HXFont{}, 18);
			if (Profile.OnHover) {
				painter->DrawText(Profile.Items[Profile.SelectingItem].Title, HXFont{}, {
									  position.X + Profile.Width / 2 - fontRect.Right / 2,
									  position.Y + 5}, theme.DropdownText, 18);
			} else {
				painter->DrawText(Profile.Items[Profile.SelectingItem].Title, HXFont{}, {
									  position.X + Profile.Width / 2 - fontRect.Right / 2,
									  position.Y + 5}, theme.DropdownText, 18);
			}
		}

		if (Profile.OnWorking) {
			DrawDropdownIcon(painter, {position.X + 4, position.Y + 8}, 8, false, theme.DropdownText);
		} else {
			DrawDropdownIcon(painter, {position.X + 4, position.Y + 8}, 8, true, theme.DropdownText);
		}

		painter->End();

		LayoutNextControl({Profile.Width, 22});
	}

	if (Profile.OnWorking) {
		Profile.scrollProfile.Size      = {Profile.Width, 100};
		Profile.scrollProfile.ViewSpace = HXPoint{Profile.Width, static_cast<HXGInt>(Profile.Items.size() * 28)};
		if (Profile.scrollProfile.ViewSpace.Y < Profile.scrollProfile.Size.Y) {
			Profile.scrollProfile.ViewSpace.Y = Profile.scrollProfile.Size.Y;
		}

		auto oldColor            = theme.ScrollerBackground;
		theme.ScrollerBackground = theme.DropdownBackground;

		BeginScroller(Profile.scrollProfile);

		SetLeftMargin(-15);

		HXGInt index = 0;
		for (auto &item : Profile.Items) {
			item.Status.Size = {Profile.Width, 22};
			if (Button(item.Title, std::ref(item.Status))) {
				Profile.OnWorking     = false;
				Profile.SelectingItem = index;
			}

			++index;
		}

		EndScroller(Profile.scrollProfile);

		theme.ScrollerBackground = oldColor;
	}

	if (returnSameLine) {
		BeginSameLine();
	}

	return Profile.SelectingItem;
}
}
